home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 25 / AACD 25.iso / AACD / Magazine / Backups / FBackNG / fbackng.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-08-30  |  17.1 KB  |  579 lines

  1. // $VER: FBackNG 1.2.1
  2. //
  3. // Purpose:     backup/mirror files
  4. // Author:      Chris De Maeyer
  5. // Copyright:   Visionary Software (C)1998-99 Source and binary FREEWARE
  6. // History:
  7. //              07-04-1999 Creation
  8. //              15-04-1999 CLI options parser
  9. //              19-04-1999 Added registration, released first beta
  10. //              23-04-1999 Added log
  11. //              24-04-1999 Added logic for backup/mirror phase
  12. //              01-05-1999 Implemented backup phase
  13. //              02-05-1999 Fixed file/dir parser
  14. //                         Enabled security
  15. //              15-05-1999 Mirror phase implemented
  16. //                         Priority option
  17. //              16-05-1999 Before/after date option
  18. //                         Move options interpretation
  19. //              27-06-1999 Removed config
  20. //              30-10-1999 Added Delete phase
  21. //              10-12-1999 Added noarch option
  22. //              29-05-2001 Removed need for keyfile
  23.  
  24. #include "dirdiver.h"
  25. #include "support.h"
  26. #include "key.h"
  27.  
  28. #define VERSION "FBackNG V1.2.1"
  29.  
  30. char version[]="\0$VER:"VERSION;
  31. char copyright[] ="(C) Visionary Software 1999 by Chris De Maeyer, FREEWARE.";
  32.  
  33. long __stack=64*1024;
  34.  
  35. struct Library *XpkBase;
  36. struct Task *thisTask;
  37.  
  38. // Date handling
  39. struct DateTime dt_Before;
  40. struct DateTime dt_After;
  41.  
  42. // CLI Options
  43. FLOPTS optflg;
  44. // CLI Parameters
  45. VAOPTS optval;
  46. // Counters
  47. ULONG   tot_files;
  48. ULONG   prc_files;
  49. ULONG   del_dirs;
  50. ULONG   tot_direc;
  51. // Globals
  52. extern char errormsg[256]; // in ddiver
  53. FILE    *logfile;
  54. long newpri;
  55.  
  56. extern int  optind;         // from getopt: next arg to process
  57. extern int  opterr;         // used by getopt
  58. extern char *optarg;        
  59.  
  60. // Functions
  61. // idiot user help
  62. void shorthelp(char *progname)
  63. {
  64.         fprintf(stderr, "Usage to get help: %s -h\n",progname);
  65. }
  66.  
  67. // -h option help
  68. void longhelp(char *progname)
  69. {
  70.         printf("\n%s - performs daily backup of filesystems.\n\n",VERSION);
  71.         printf("%s\n",copyright);
  72.        
  73.         printf("\nUsage: %s -b <path> -o <path>\n",progname);
  74.         printf("           [-s][-r][-e][-t][-n][-m][-k][-c <packer>\n");
  75.         printf("           [-d][-v <0|1|2|3>][-i <pri>][-g <pattern>]\n");
  76.         printf("           [-u][-y <date>][-a <date>][-l <file>]\n\n");
  77. }
  78.  
  79. // if CLI option with arg, filter out arg
  80. void getarg(char *progname,char opt,char *src,char *arg,int size)
  81. {
  82.     int error = 0;
  83.     
  84.     if(src!=NULL)
  85.     {
  86.           if((*src == '-') || (*src == '\0'))
  87.                   error = 1;
  88.           else
  89.                   strncpy(arg,src,size);
  90.     }
  91.     else
  92.           error = 1;
  93.                  
  94.     if(error)
  95.     {
  96.           fprintf(stderr,"%s: fatal: argument required for -%c\n",progname,opt);
  97.           exit(1);
  98.     }
  99. }
  100.  
  101. void initarg(void)
  102. {
  103.     // init option flags and values
  104.     optflg.opt_source          = 0; // source path (from) REQ
  105.     optflg.opt_dest            = 0; // destination path (to) REQ
  106.     optflg.opt_simulate        = 0; // simulate mode
  107.     optflg.opt_recursive       = 0; // recursive traversing
  108.     optflg.opt_verbose         = 0; // verbosity level
  109.     optflg.opt_priority        = 0; // set priority
  110.     optflg.opt_compress        = 0; // enable compression
  111.     optflg.opt_every           = 0; // ignore archive bit = all
  112.     optflg.opt_touch           = 0; // modify date/timestamp on destination
  113.     optflg.opt_nonotes         = 0; // do not copy filenotes
  114.     optflg.opt_pattern         = 0; // only process files matching pattern
  115.     optflg.opt_log             = 0; // write to log
  116.     optflg.opt_before          = 0; // only files < date (incl. given date)
  117.     optflg.opt_after           = 0; // only files > date (not incl. date)
  118.     optflg.opt_mirror          = 0; // do mirror phase
  119.     optflg.opt_skip            = 0; // skip backup phase
  120.     optflg.opt_delete          = 0; // do delete phase
  121.     optflg.opt_noarch          = 0; // do not set archive flag
  122.  
  123.     optval.val_temp[0]         = 0;
  124.     optval.val_source[0]       = 0;
  125.     optval.val_dest[0]         = 0;
  126.     optval.val_verbose         = OUT_NORMAL;
  127.     optval.val_compress[0]     = 0;
  128.     optval.val_pattern[0]      = 0;
  129.     optval.val_log[0]          = 0;
  130.     optval.val_before[0]       = 0;
  131.     optval.val_after[0]        = 0;
  132.  
  133.     logfile = NULL;
  134. }
  135.  
  136. void oncearg(char *prog)
  137. {
  138.     int error;
  139.     char username[LEN_PATH];
  140.     
  141.     // initiate log if active
  142.     if(optflg.opt_log)
  143.     {
  144.         if((error = put_LogOneMsg(optval.val_log,"***** FBackNG Started...\n"))!=DD_OK)
  145.         {
  146.             fprintf (stderr, "%s: fatal: could not initiate log (%d)\n",prog,error);
  147.             exit(1);
  148.         }
  149.     }
  150.  
  151.     // display banner after CLI parsing
  152.     if(optval.val_verbose>OUT_QUIET)
  153.     {
  154.         printf("FBackNG - the daily file backup/mirror tool......\n");
  155.         printf("(C)1999 Visionary Software - FREEWARE.\n\n");
  156.     }    
  157.  
  158.     // is the user registered
  159.     // error = GetRegisteredUser("S:fbackng.key",username);
  160.     
  161.     //if(error==0)
  162.     //{
  163.         optflg.opt_validuser = TRUE;
  164.     //    memcpy(optval.val_user,&username[17],LEN_PATH-17);
  165.         
  166.     //    sprintf(errormsg,"Registered to %s\n",optval.val_user);
  167.     //    check_write_log(NULL);
  168.         
  169.     //    if(optval.val_verbose>OUT_QUIET)
  170.     //            printf("%s\n",errormsg);
  171.     //}
  172.     //else
  173.     //{
  174.     //    optflg.opt_validuser = FALSE;
  175.        
  176.         // disable some stuff
  177.     //    optflg.opt_recursive = 0;
  178.          
  179.     //    check_write_log("Unregistered Evaluation Version - no support !\n");
  180.         
  181.     //    if(optval.val_verbose>OUT_QUIET)
  182.     //    {
  183.     //            printf("This is an Unregistered Evaluation Shareware program.\n");
  184.     //            printf("Some options are disabled in this state.\n");
  185.     //            printf("To encourage further development and to get support you must\n");
  186.     //            printf("register your copy of the program now.\n\n");
  187.     //            printf("Hit return to go on...\n");
  188.     //            getchar();
  189.     //    }
  190.     //}
  191. }    
  192.        
  193. void intarg(char *prog)
  194. {
  195.     if(optflg.opt_skip)
  196.     {
  197.         if(!optflg.opt_mirror)
  198.         {
  199.                 sprintf(errormsg,"%s: fatal: skip without mirror\n",prog);
  200.                 check_write_log(NULL);
  201.                 fprintf (stderr, "%s",errormsg);
  202.                 exit (1);
  203.         } 
  204.     }
  205.     
  206.     if(optflg.opt_before)
  207.     {
  208.            dt_Before.dat_Format  = FORMAT_DOS;
  209.            dt_Before.dat_StrDate = optval.val_before;
  210.            dt_Before.dat_StrTime = NULL;
  211.            dt_Before.dat_Flags   = 0L;
  212.            dt_Before.dat_StrDay  = NULL;
  213.         
  214.            if(!(StrToDate(&dt_Before)))
  215.            {
  216.                 sprintf(errormsg,"%s: fatal: invalid date for -y\n",prog);
  217.                 check_write_log(NULL);
  218.                 fprintf (stderr, "%s",errormsg);
  219.                 exit (1);
  220.            }
  221.     }
  222.  
  223.     if(optflg.opt_after)
  224.     {
  225.            dt_After.dat_Format  = FORMAT_DOS;
  226.            dt_After.dat_StrDate = optval.val_after;
  227.            dt_After.dat_StrTime = NULL;
  228.            dt_After.dat_Flags   = 0L;
  229.            dt_After.dat_StrDay  = NULL;
  230.         
  231.            if(!(StrToDate(&dt_After)))
  232.            {
  233.                 sprintf(errormsg,"%s: fatal: invalid date for -a\n",prog);
  234.                 check_write_log(NULL);
  235.                 fprintf (stderr, "%s",errormsg);
  236.                 exit (1);
  237.            }
  238.     }
  239.         
  240.     // if not configuration mode then both source + dest paths must be there
  241.         if ((optflg.opt_source && optflg.opt_dest)==FALSE)
  242.         {
  243.                 sprintf(errormsg,"%s: fatal: source and destination not found\n",prog);
  244.                 check_write_log(NULL);
  245.                 fprintf (stderr, "%s",errormsg);
  246.                 exit (1);
  247.         }
  248.         
  249.         // check given paths for access
  250.         if(!(Check_Dir(optval.val_source)))
  251.         {
  252.             sprintf (errormsg, "%s: fatal: source path not found\n",prog);
  253.             check_write_log(NULL);
  254.             fprintf (stderr, "%s",errormsg);
  255.             exit(1);
  256.         }
  257.         if(!(Check_Dir(optval.val_dest)))
  258.         {
  259.             sprintf (errormsg, "%s: fatal: destination path not found\n",prog);
  260.             check_write_log(NULL);
  261.             fprintf (stderr, "%s",errormsg);
  262.             exit(1);
  263.         }
  264.                         
  265.         // if no pattern given, select all
  266.         if(strlen(optval.val_pattern)==0)
  267.                 strcpy(optval.val_pattern,"#?");
  268.     
  269.     // if compress mode, open xpk library
  270.     if(optflg.opt_compress)
  271.     {
  272.         if(!(XpkBase=OpenLibrary(XPKNAME,0)))
  273.         {
  274.             sprintf (errormsg, "%s: fatal: could not open xpk library\n",prog);
  275.             check_write_log(NULL);
  276.             fprintf (stderr, "%s",errormsg);
  277.             exit(1);
  278.         }
  279.     }    
  280.     
  281.     if(optflg.opt_priority)
  282.     {
  283.         if(newpri>5) newpri = 5;
  284.         SetTaskPri(thisTask,newpri);         
  285.  
  286.         sprintf(errormsg,"Priority set to %ld\n",newpri);
  287.         check_write_log(NULL);
  288.         
  289.         if(optval.val_verbose>OUT_QUIET)
  290.                 printf("%s\n",errormsg);
  291.     }    
  292.   
  293. }
  294.                           
  295. int main(int argc, char *argv[])
  296. {
  297.     char        c;
  298.     int         dderror,count;
  299.     char        root[LEN_PATH];
  300.     
  301.     thisTask = FindTask(NULL);
  302.  
  303.     initarg();
  304.        
  305.     opterr = 1;                 // so getopt will print err msg
  306.     count = 0;
  307.     
  308.     // parse options and fill structures
  309.     while ((c = getopt (argc, argv, "bosrvicetnglyamkduh")) != EOF)
  310.     {
  311.         // error = 0;
  312.         
  313.         switch (c)
  314.         {
  315.                 case 'b':
  316.                         count++;
  317.                         optflg.opt_source++;
  318.                         getarg(argv[0],c,argv[optind],optval.val_source,LEN_PATH);
  319.                         optind++;
  320.                         break;
  321.                         
  322.                 case 'o':
  323.                         count++;
  324.                         optflg.opt_dest++;
  325.                         getarg(argv[0],c,argv[optind],optval.val_dest,LEN_PATH);
  326.                         optind++;
  327.                         break;
  328.  
  329.                 case 's':
  330.                         count++;
  331.                         optflg.opt_simulate++;
  332.                         break;
  333.                         
  334.                 case 'r':
  335.                         count++;
  336.                         optflg.opt_recursive++;
  337.                         break;
  338.                         
  339.                 case 'v':
  340.                         count++;
  341.                         optflg.opt_verbose++;
  342.                         getarg(argv[0],c,argv[optind],optval.val_temp,LEN_PATH);
  343.                         optval.val_verbose = atoi(optval.val_temp);
  344.                         optind++;
  345.                         break;
  346.                 
  347.                 case 'i':
  348.                         count++;
  349.                         optflg.opt_priority++;
  350.                         getarg(argv[0],c,argv[optind],optval.val_temp,LEN_PATH);
  351.                         newpri = atol(optval.val_temp);
  352.                         optind++;
  353.                         break;
  354.                         
  355.                 case 'c':
  356.                         count++;
  357.                         optflg.opt_compress++;
  358.                         getarg(argv[0],c,argv[optind],optval.val_compress,LEN_STRING);
  359.                         optind++;
  360.                         break;
  361.                         
  362.                 case 'e':
  363.                         count++;
  364.                         optflg.opt_every++;
  365.                         break;
  366.                         
  367.                 case 't':
  368.                         count++;
  369.                         optflg.opt_touch++;
  370.                         break;
  371.                         
  372.                 case 'n':
  373.                         count++;
  374.                         optflg.opt_nonotes++;
  375.                         break;
  376.                         
  377.                 case 'g':
  378.                         count++;
  379.                         optflg.opt_pattern++;
  380.                         getarg(argv[0],c,argv[optind],optval.val_pattern,LEN_STRING);
  381.                         optind++;
  382.                         break;
  383.                         
  384.                 case 'l':
  385.                         count++;
  386.                         optflg.opt_log++;
  387.                         getarg(argv[0],c,argv[optind],optval.val_log,LEN_PATH);
  388.                         optind++;
  389.                         break;
  390.                         
  391.                 case 'y':
  392.                         count++;
  393.                         optflg.opt_before++;
  394.                         getarg(argv[0],c,argv[optind],optval.val_before,LEN_STRING);
  395.                         optind++;
  396.                         break;
  397.                         
  398.                 case 'a':
  399.                         count++;
  400.                         optflg.opt_after++;
  401.                         getarg(argv[0],c,argv[optind],optval.val_after,LEN_STRING);
  402.                         optind++;
  403.                         break;
  404.  
  405.                 case 'm':
  406.                         count++;
  407.                         optflg.opt_mirror++;
  408.                         break;
  409.  
  410.                 case 'd':
  411.                         count++;
  412.                         optflg.opt_delete++;
  413.                         break;
  414.  
  415.                 case 'k':
  416.                         count++;
  417.                         optflg.opt_skip++;
  418.                         break;
  419.  
  420.                 case 'u':
  421.                         count++;
  422.                         optflg.opt_noarch++;
  423.                         break;
  424.  
  425.                 case 'h':
  426.                         longhelp(argv[0]);
  427.                         exit(0);
  428.                         
  429.                 case '?':
  430.                         shorthelp(argv[0]);
  431.                         exit(0);
  432.         }
  433.     }
  434.  
  435.     // parsing finished, check consistency
  436.     if (count == 0)
  437.     {
  438.         shorthelp(argv[0]);
  439.         exit(1);
  440.     }
  441.  
  442.     oncearg(argv[0]);
  443.  
  444.     // Dump the options given to the logfile if active
  445.     if(optflg.opt_log)
  446.     {
  447.         for(c=1; c<argc; c++)
  448.         {
  449.             sprintf(errormsg,"Argument(%d) = %s\n",c,argv[c]);
  450.             check_write_log(NULL);
  451.         }
  452.     }
  453.  
  454.     intarg(argv[0]);
  455.  
  456.     strcpy(root,optval.val_source);
  457.     
  458.     if(!optflg.opt_skip)
  459.     {         
  460.         tot_files = 0;
  461.         tot_direc = 0;
  462.         prc_files = 0;
  463.  
  464.         check_write_log("----- Backup Phase\n");    
  465.  
  466.         if(optval.val_verbose>OUT_QUIET)
  467.         {
  468.                 printf("%s\n",STR_BACKUPPHASE);    
  469.         }
  470.                  
  471.         dderror = DirDiver(root,BACKUP_PHASE);
  472.     
  473.         if(dderror != DD_OK)
  474.         {
  475.                 sprintf (errormsg,"%s: fatal: backup process error (%d)\n",argv[0],dderror);
  476.                 check_write_log(NULL);
  477.         
  478.                 fprintf (stderr, "%s\n",errormsg);
  479.                 check_write_log("***** FBackNG Ended.\n");    
  480.                 exit(1);
  481.         }                
  482.  
  483.         if(optval.val_verbose>OUT_QUIET)
  484.         {
  485.                 sprintf(errormsg,"Total files: %ld, Total Directories: %ld\n",tot_files,tot_direc);
  486.                 check_write_log(NULL);
  487.                 printf("%s",errormsg);
  488.         
  489.                 sprintf(errormsg,"Files saved: %ld\n",prc_files);
  490.                 check_write_log(NULL);
  491.                 printf("%s",errormsg);
  492.         }
  493.     }    
  494.  
  495.     if(optflg.opt_mirror)
  496.     {             
  497.         tot_files = 0;
  498.         tot_direc = 0;
  499.         prc_files = 0;
  500.  
  501.         check_write_log("----- Mirror Phase\n");    
  502.  
  503.         if(optval.val_verbose>OUT_QUIET)
  504.         {
  505.                 printf("\n%s\n",STR_MIRRORPHASE);    
  506.         }
  507.  
  508.         strcpy(root,optval.val_dest);
  509.   
  510.         dderror = DirDiver(root,MIRROR_PHASE);
  511.     
  512.         if(dderror != DD_OK)
  513.         {
  514.                 sprintf (errormsg,"%s: fatal: mirror process error (%d)\n",argv[0],dderror);
  515.                 check_write_log(NULL);
  516.         
  517.                 fprintf (stderr, "%s\n",errormsg);
  518.                 check_write_log("***** FBackNG Ended.\n");    
  519.                 exit(1);
  520.         }                
  521.  
  522.         if(optval.val_verbose>OUT_QUIET)
  523.         {
  524.                 sprintf(errormsg,"Total files: %ld, Total Directories: %ld\n",tot_files,tot_direc);
  525.                 check_write_log(NULL);
  526.                 printf("%s",errormsg);
  527.         
  528.                 sprintf(errormsg,"Files deleted: %ld\n",prc_files);
  529.                 check_write_log(NULL);
  530.                 printf("%s",errormsg);
  531.         }
  532.     
  533.     }
  534.  
  535.     if(optflg.opt_delete)
  536.     {             
  537.         tot_files = 0;
  538.         tot_direc = 0;
  539.         del_dirs = 0;
  540.  
  541.         check_write_log("----- Delete Phase\n");    
  542.  
  543.         if(optval.val_verbose>OUT_QUIET)
  544.         {
  545.                 printf("\n%s\n",STR_DELETEPHASE);    
  546.         }
  547.  
  548.         strcpy(root,optval.val_dest);
  549.   
  550.         dderror = DirCleaner(root);
  551.     
  552.         if(dderror != DD_OK)
  553.         {
  554.                 sprintf (errormsg,"%s: fatal: delete process error (%d)\n",argv[0],dderror);
  555.                 check_write_log(NULL);
  556.         
  557.                 fprintf (stderr, "%s\n",errormsg);
  558.                 check_write_log("***** FBackNG Ended.\n");    
  559.                 exit(1);
  560.         }                
  561.  
  562.         if(optval.val_verbose>OUT_QUIET)
  563.         {
  564.                 sprintf(errormsg,"Total Directories: %ld\n",tot_direc);
  565.                 check_write_log(NULL);
  566.                 printf("%s",errormsg);
  567.         
  568.                 sprintf(errormsg,"Directories deleted: %ld\n",del_dirs);
  569.                 check_write_log(NULL);
  570.                 printf("%s",errormsg);
  571.         }
  572.     
  573.     }
  574.  
  575.  
  576.     check_write_log("***** FBackNG Ended.\n");    
  577.     exit(0);
  578. }    
  579.